/*
 * CannonicalSystem.h
 *
 *  Created on: Jan 9, 2012
 *      Author: allan
 */

#ifndef CANNONICALSYSTEM_H_
#define CANNONICALSYSTEM_H_

// C++ includes
#include <string>
#include <vector>
using namespace std;

// Eigen includes
#include <Eigen/Core>
using namespace Eigen;

// GeoReact includes
#include <Core/Multiphase.h>
#include <Core/ReactionSystem.h>

class CannonicalSystem
{
public:
	CannonicalSystem();
	
	CannonicalSystem(const Multiphase& multiphase,
		const ReactionSystem& equilibrium_reactions,
		const vector<string>& primary_species,
		const vector<string>& equilibrium_species);
	
	CannonicalSystem(const Multiphase& multiphase,
		const ReactionSystem& equilibrium_reactions,
		const ReactionSystem& kinetic_reactions,
		const vector<string>& primary_species,
		const vector<string>& equilibrium_species,
		const vector<string>& kinetic_species);
	
	const unsigned
	GetNumSpecies() const;
	
	const unsigned
	GetNumPrimarySpecies() const;
	
	const unsigned
	GetNumEquilibriumSpecies() const;
	
	const unsigned
	GetNumKineticSpecies() const;
	
	const Multiphase&
	GetMultiphase() const;
	
	const ReactionSystem&
	GetEquilibriumReactions() const;
	
	const ReactionSystem&
	GetKineticReactions() const;
	
	const vector<string>&
	GetPrimarySpecies() const;
	
	const vector<string>&
	GetEquilibriumSpecies() const;
	
	const vector<string>&
	GetKineticSpecies() const;
	
	const vector<Index>&
	GetIndexesPrimarySpecies() const;
	
	const vector<Index>&
	GetIndexesEquilibriumSpecies() const;
	
	const vector<Index>&
	GetIndexesKineticSpecies() const;
	
	void
	SetCompositionPrimarySpecies(const VectorXd& nj, VectorXd& n) const;
	
	void
	SetCompositionEquilibriumSpecies(const VectorXd& ne, VectorXd& n) const;
	
	void
	SetCompositionKineticSpecies(const VectorXd& nk, VectorXd& n) const;
	
	const MatrixXd
	StoichiometricMatrixUej() const;
	
	const MatrixXd
	StoichiometricMatrixUee() const;
	
	const MatrixXd
	StoichiometricMatrixUkj() const;
	
	const MatrixXd
	StoichiometricMatrixUkk() const;
	
	const MatrixXd
	StoichiometricMatrixVej() const;
	
	const VectorXd
	CompositionPrimarySpecies(const VectorXd& n) const;
	
	const VectorXd
	CompositionEquilibriumSpecies(const VectorXd& n) const;
	
	const VectorXd
	CompositionKineticSpecies(const VectorXd& n) const;
	
	const VectorXd
	KineticRatesPrimarySpecies(const VectorXd& rk) const;
	
	const VectorXd
	KineticRatesKineticSpecies(const VectorXd& rk) const;
	
	const VectorXd
	TotalCompositionPrimarySpecies(const VectorXd& n) const;
	
private:
	/// The multiphase instance
	Multiphase multiphase;
	
	/// The equilibrium-controlled reactions
	ReactionSystem equilibrium_reactions;
	
	/// The kinetically-controlled reactions
	ReactionSystem kinetic_reactions;
	
	/// The primary species
	vector<string> primary_species;
	
	/// The equilibrium species
	vector<string> equilibrium_species;
	
	/// The kinetic species
	vector<string> kinetic_species;
	
	/// The indexes of the primary species
	vector<Index> indexes_primary_species;
	
	/// The indexes of the equilibrium species
	vector<Index> indexes_equilibrium_species;
	
	/// The indexes of the kinetic species
	vector<Index> indexes_kinetic_species;
	
	/// The stoichiometric matrices
	MatrixXd uej, uee, ukj, ukk, vej, vkj;
};

#endif /* CANNONICALSYSTEM_H_ */
